package com.bckj.fastboot.iot.parse.core;

import com.bckj.fastboot.core.extra.cache.CacheOps;
import com.bckj.fastboot.iot.api.service.IotAlarmRuleRemoteService;
import com.bckj.fastboot.iot.common.dto.request.IotAlarmDataRequest;
import com.bckj.fastboot.iot.common.entity.IotAlarmRule;
import com.bckj.fastboot.iot.parse.core.alarmrule.AlarmRuleConditionEvaluator;
import com.bckj.fastboot.iot.parse.core.alarmrule.AlarmRuleConditionEvaluatorFactory;
import com.bckj.fastboot.iot.parse.core.alarmrule.RuleEvaluatorType;
import com.bckj.fastboot.iot.common.constant.IotParseCacheConstants;
import com.bckj.fastboot.iot.parse.service.IotAlarmDataService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * IotAlarmTrigger
 *
 * @author wfc
 **/
@Slf4j
@Component
public class IotAlarmTrigger {

    @Resource
    private IotAlarmDataService iotAlarmDataService;
    @Resource
    private IotAlarmRuleRemoteService iotAlarmRuleRemoteService;
    @Resource
    private CacheOps cacheOps;

    public List<IotAlarmRule> findRules(String protocolCode, String cmd) {
        String cacheKey = protocolCode + cmd;
        var cache = cacheOps.localCache(IotParseCacheConstants.IOT_ALARM_RULE_CACHE_NAME);
        return cacheOps.runCaching(cache, () -> iotAlarmRuleRemoteService.findRules(protocolCode, cmd), cacheKey);
    }

    /**
     * 触发报警处理
     */
    public void trigger(ProtocolParseContext context) {
        String devCode = context.getDevCode();
        String protocolCode = context.getProtocolCode();
        String cmd = context.getCmd();
        Map<String, Object> dataMap = context.getDataMap();
        // 获取报警规则
        List<IotAlarmRule> rules = findRules(protocolCode, cmd);
        if (rules.isEmpty()) {
            log.info("没有报警规则 devCode={},protocolCode={},cmd={}", devCode, protocolCode, cmd);
            return;
        }
        Map<String, Object> alarmDataMap = new HashMap<>();
        for (IotAlarmRule rule : rules) {
            // 触发报警处理
            Object o = dataMap.get(rule.getItemCode());
            if (o != null) {
                Map<String, Object> params = new HashMap<>();
                params.put("value", o);
                RuleEvaluatorType type = RuleEvaluatorType.valueOf(rule.getEvaluatorType().toUpperCase());
                AlarmRuleConditionEvaluator evaluator = AlarmRuleConditionEvaluatorFactory.getEvaluator(type);
                if (evaluator.eval(rule.getTriggerCondition(), params)) {
                    // 触发报警处理
                    alarmDataMap.put(rule.getAlarmCode(), o);
                }
            }
        }
        if (alarmDataMap.isEmpty()) {
            log.info("没有触发报警 devCode={}", devCode);
            return;
        }
        IotAlarmDataRequest request = new IotAlarmDataRequest();
        request.setDevCode(context.getDevCode());
        request.setCmd(cmd);
        request.setDataMap(alarmDataMap);
        iotAlarmDataService.handle(request);
    }
}
